package ym.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Collections;

/**
 * Security配置类
 */

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)// 开启鉴权配置注解
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    //解决跨域，相关文章http://t.csdnimg.cn/3LYOI
    CorsConfigurationSource configurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 允许cookies跨域
        corsConfiguration.setAllowCredentials(true);
        // 允许的请求方法
        corsConfiguration.setAllowedMethods(Collections.singletonList("*"));
        // 允许的请求头
        corsConfiguration.setAllowedHeaders(Collections.singletonList("*"));
        // 预检请求的缓存时间（秒），即在这个时间段里，对于相同的跨域请求不会再预检了
        corsConfiguration.setMaxAge(3600L);
        //允许跨域访问的站点
        corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
        //对所有URL生效
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 自定义表单登录
        http.formLogin()
                .usernameParameter("username") // 用户名项
                .passwordParameter("password") // 密码项
                .loginProcessingUrl("/back/login") // 登录提交路径
                .successHandler(new MyLoginSuccessHandler()) // 登录成功处理器
                .failureHandler(new MyLoginFailureHandler()); // 登录失败处理器


        // 权限拦截配置
        http.authorizeRequests()
                .antMatchers("/back/login").permitAll() // 登录不需要认证
                .antMatchers("/").permitAll()
                .antMatchers("/file/**").permitAll()//放行文件资接口
                .antMatchers("/front/**").permitAll()//放行前台接口
                .antMatchers("/back/index/**").permitAll()//放行前后端整合后的后台打包文件
                .antMatchers("/back/assets/**").permitAll()//放行前后端整合后的后台打包文件
                .anyRequest().authenticated(); // 其余请求都需要认证


        // 退出登录配置
        http.logout()
                .logoutUrl("/back/logout") // 退出登录路径
                .logoutSuccessHandler(new MyLogoutSuccessHandler()) // 登出成功处理器
                .clearAuthentication(true) // 清除认证数据
                .invalidateHttpSession(true); // 清除session


        // 异常处理
        http.exceptionHandling()
                .authenticationEntryPoint(new MyAuthenticationEntryPoint()) // 未登录处理器
                .accessDeniedHandler(new MyAccessDeniedHandler()); // 权限不足处理器


        // 关闭csrf防护,取消跨站请求伪造防护
        http.csrf().disable();

        // 开启跨域访问
        http.cors().configurationSource(configurationSource());
//        http.cors();

    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
